
//
// 101019 - AH - Created.
// 101111a- AH - Missing java doc added.
// 101111b- AH - E_ARRAY.
// 101112 - AH - bidirectional().
// 110207 - AH - getBidirectionalKey().
//

package org.soekrat.engine.network;

/**
 * <p>
 *   Edge in
 *   {@link Network}.
 * </p>
 * @author Arne Halvorsen (AH)
 * @author Laetitia Le Chatton (LLC)
 */
public final class NetworkEdge 
{
  private final NetworkNode m_from;
  
  private final NetworkNode m_to;
  
  /**
   * <p>
   *   Constructor.
   * </p>
   * @param from The node edge is from.
   * @param to   The node edge is to.
   */
  NetworkEdge(NetworkNode from, NetworkNode to){ m_from=from; m_to=to; }
  
  /**
   * <p>
   *   Gets 
   *   {@link NetworkNode} edge is from.
   * </p>
   * @return {@code NetworkNode}.
   */
  public NetworkNode from(){ return m_from; }
  
  /**
   * <p>
   *   Gets 
   *   {@link NetworkNode} edge is to.
   * </p>
   * @return {@code NetworkNode}.
   */
  public NetworkNode to(){ return m_to; }
  
  /**
   * <p>
   *   Gets the oposite given node in {@code this} edge.
   * </p>
   * @param node {@link Node} to get the opposite.
   * @return Oposite.
   * @throws IllegalArgumentException If {@code node} is not part of 
   *         {@code this} edge.
   */
  public NetworkNode getOposite(NetworkNode node)
  {
    if (node!=m_from && node!=m_to)
    {
      throw new IllegalArgumentException("node : "+node+" not in edge");
    }
    
    return node==m_from ? m_to : m_from;
  }
  
  /**
   * <p>
   *   Tells if there also is a link between 
   *   {@link #to()} and
   *   {@link #from()}.
   * </p>
   * @return {@code true} if is bidirectional, {@code false} if is not.
   */
  public boolean bidirectional()
  {
    Network network=m_from.getNetwork();
    return network.hasLink(m_to, m_from);
  }
  
  /**
   * <p>
   *   Gets key for {@code this} that is equal for an edge that is opposite.
   * </p>
   * <p>
   *   This will always return a key but there may not actually exist an
   *   opposite edge, use
   *   {@link #bidirectional()} to find out.
   * </p>
   * @return Key.
   */
  public String getBidirectionalKey()
  {
    String name0=m_from.getName();
    String name1=m_to.getName();
    return name0.compareTo(name1)<0 ? name0+name1 : name1+name0;
  }
  
  @Override
  public String toString() { return "e"; }
  
  /**
   * <p>
   *   The empty array shared. 
   * </p>
   */
  public static final NetworkEdge[] E_ARRAY=new NetworkEdge[0];
  
}
